package com.itheima.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;


//@WebFilter(urlPatterns = "/*", filterName = "shiroLoginFilter")
public class ShiroLoginFilter implements Filter {

    /**
     *  程序启动的时候调用
     *
     * @param filterConfig
     * @throws ServletException
     */
    @Override
    public void init(FilterConfig filterConfig) {
        System.out.println("程序启动");
    }

    /**
     * 每次请求访问时调用
     *
     * @param servletRequest
     * @param servletResponse
     * @param chain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        // 允许哪些Origin发起跨域请求
        String orgin = request.getHeader("Origin");
        response.setHeader("Access-Control-Allow-Origin", orgin);
        // 允许请求的请求类型
        response.setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE,PUT");
        //多少秒内,不需要再发送预检验请求，可以缓存该结果
        response.setHeader("Access-Control-Max-Age", "3600");
        //表明它允许跨域请求头中有哪些参数
        response.setHeader("Access-Control-Allow-Headers", "x-auth-token,Origin,Access-Token,X-Requested-With,Content-Type,Accept,token");
        //是否允许浏览器携带用户身份信息（cookie）
        response.setHeader("Access-Control-Allow-Credentials", "true");
        //cors试探性请求,拦截到OPTIONS类型请求，直接返回结果
        String urlType = request.getMethod();
        if (urlType.equals("OPTIONS")) {
            response.setStatus(200);
            return;
        }

        //不进行XSS攻击处理的接口(一般都是要用到富文本的接口)，只是不用过滤HTML字符
        List<String> urlList=new ArrayList<>();
        urlList.add("/assess/addAssessUser");
        urlList.add("/article/addJournalism");
        urlList.add("/article/updateArticle");
        urlList.add("/course/addCourse");
        urlList.add("/course/updateCourse");
        urlList.add("/course_chapters/updateCourseChapters");
        urlList.add("/course_chapters/addCourseChapters");
        urlList.add("/competitionTitbits/updateCompetitionTitbitsOne");
        urlList.add("/competitionTitbits/addCompetitionTitbitsOne");
        urlList.add("/user/addUser");
        urlList.add("/user/updateUser");
        urlList.add("/text/addText");
        urlList.add("/text/updateText");
        urlList.add("/practice_finance/addOrUpdatePracticeFinanceSystem");
        urlList.add("/practice_structure/addOrUpdatePracticeStructureSynopsis");
        //判断当前接口是要进行XSS攻击处理的还是不要的(在不过滤列表里面有就是不过滤，没有则要过滤)，只是不用过滤HTML字符
        if(urlList.stream().filter(data -> data.equals(request.getRequestURI())).collect(Collectors.toList()).isEmpty()){
            XssHttpServletRequestWrapper.HTML_TYPE = true;
            XssHttpServletRequestWrapper.SQL_TYPE = true;
        }else {
            XssHttpServletRequestWrapper.HTML_TYPE = false;
            XssHttpServletRequestWrapper.SQL_TYPE = true;
        }
        //处理XSS攻击(其实就是SQL和HTML/CSS/JS注入攻击)，方法是重写HttpServletRequest这些请求实体类的参数过滤规则，然后替换掉原生默认的
        XssHttpServletRequestWrapper xssHttpServletRequestWrapper=new XssHttpServletRequestWrapper(request);
        chain.doFilter(xssHttpServletRequestWrapper, response);
    }

    /**
     * 程序关闭的时候调用
     */
    @Override
    public void destroy() {
        System.out.println("程序关闭");
    }
}
